package top.cardone.data.support;

import top.cardone.context.ApplicationContextHolder;
import top.cardone.core.util.action.Action2;
import top.cardone.core.util.func.Func1;
import top.cardone.core.util.func.Func2;

/**
 * Created by Administrator on 2015/8/9.
 */
public class DefaultDataOperationsSupport implements DataOperationsSupport {
    @Override
    public <R1, T1, T2, T3> void action(String parseBeanId, T1 t1, T2 t2, String t3BeanId, Action2<R1, T3> dataOperationsAction) {
        ApplicationContextHolder.action(Func2.class, parseFunc -> {
            ApplicationContextHolder.action(o -> {
                R1 r1 = (R1) parseFunc.func(t1, t2);

                T3 t3 = (T3) o;

                dataOperationsAction.action(r1, t3);
            }, t3BeanId);
        }, parseBeanId);
    }

    @Override
    public <R1, T1, T2, T3> void action(String parseBeanId, String t3BeanId, Action2<Func2<R1, T1, T2>, T3> dataOperationsAction) {
        ApplicationContextHolder.action(Func2.class, parseFunc -> {
            ApplicationContextHolder.action(o -> {
                T3 t3 = (T3) o;

                dataOperationsAction.action(parseFunc, t3);
            }, t3BeanId);
        }, parseBeanId);
    }

    @Override
    public <R1, T1, T2> void action(String parseBeanId, T1 t1, String t2BeanId, Action2<R1, T2> dataOperationsAction) {
        ApplicationContextHolder.action(Func1.class, parseFunc -> {
            ApplicationContextHolder.action(o -> {
                R1 r1 = (R1) parseFunc.func(t1);

                T2 t2 = (T2) o;

                dataOperationsAction.action(r1, t2);
            }, t2BeanId);
        }, parseBeanId);
    }

    @Override
    public <R1, R2, T1, T2, T3> R1 func(String parseBeanId, T1 t1, T2 t2, String t3BeanId, Func2<R1, R2, T3> dataOperationsFunc) {
        return ApplicationContextHolder.func(Func2.class, parseFunc -> {
            return ApplicationContextHolder.func(o -> {
                R2 r2 = (R2) parseFunc.func(t1, t2);

                T3 t3 = (T3) o;

                return dataOperationsFunc.func(r2, t3);
            }, t3BeanId);
        }, parseBeanId);
    }

    @Override
    public <R1, R2, T1, T2, T3> R1 func(String parseBeanId, String t3BeanId, Func2<R1, Func2<R2, T1, T2>, T3> dataOperationsFunc) {
        Func2<R2, T1, T2> parseFunc = ApplicationContextHolder.getBean(Func2.class, parseBeanId);

        if (parseFunc == null) {
            return null;
        }

        return ApplicationContextHolder.func(o -> {
            T3 t3 = (T3) o;

            return dataOperationsFunc.func(parseFunc, t3);
        }, t3BeanId);
    }

    @Override
    public <R1, R2, T1, T2> R1 func(String parseBeanId, T1 t1, String t2BeanId, Func2<R1, R2, T2> dataOperationsFunc) {
        return ApplicationContextHolder.func(Func1.class, parseFunc -> {
            return ApplicationContextHolder.func(o -> {
                R2 r2 = (R2) parseFunc.func(t1);

                T2 t2 = (T2) o;

                return dataOperationsFunc.func(r2, t2);
            }, t2BeanId);
        }, parseBeanId);
    }
}
